package com.weijianhuawen.wjblog.admin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.base.FinalizableWeakReference;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.weijianhuawen.wjblog.admin.mode.vo.dashboard.FindDashboardPvStatisticsInfoRspVo;
import com.weijianhuawen.wjblog.admin.mode.vo.dashboard.FindDashboardStatisticsInfoRspVo;
import com.weijianhuawen.wjblog.admin.service.AdminDashboardService;
import com.weijianhuawen.wjblog.common.constants.Constants;
import com.weijianhuawen.wjblog.common.domain.dos.ArticleDo;
import com.weijianhuawen.wjblog.common.domain.dos.ArticlePublishCountDo;
import com.weijianhuawen.wjblog.common.domain.dos.CategoryDo;
import com.weijianhuawen.wjblog.common.domain.dos.StatisticsArticlePvDo;
import com.weijianhuawen.wjblog.common.domain.mapper.ArticleMapper;
import com.weijianhuawen.wjblog.common.domain.mapper.CategoryMapper;
import com.weijianhuawen.wjblog.common.domain.mapper.StatisticsArticlePvMapper;
import com.weijianhuawen.wjblog.common.domain.mapper.TagMapper;
import com.weijianhuawen.wjblog.common.utils.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.jni.Local;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @version: java version 8
 * @Author: weijianhuawen
 * @description:
 * @date: 2024-11-01 14:43
 */

@Service
@Slf4j
public class AdminDashboardServiceImpl implements AdminDashboardService {
    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private CategoryMapper categoryMapper;
    @Resource
    private TagMapper tagMapper;

    @Resource
    private StatisticsArticlePvMapper statisticsArticlePvMapper;
    @Override
    public Response findDashboardStatistics() {
        // 查询文章总数
        Long articleTotalCount = articleMapper.selectCount(Wrappers.emptyWrapper());
        // 查询分类总数
        Long categoryTotalCount = categoryMapper.selectCount(Wrappers.emptyWrapper());
        // 查询标签总数
        Long tagTotalCount =  tagMapper.selectCount(Wrappers.emptyWrapper());
        // 查询pv总数
        List<ArticleDo> articleDos = articleMapper.selectAllByReadNum();
        Long pvTotalCount = 0L;
        if (!CollectionUtils.isEmpty(articleDos)) {
            pvTotalCount = articleDos.stream().mapToLong(ArticleDo::getReadNum).sum();
        }

        // 转为vo
        FindDashboardStatisticsInfoRspVo findDashboardStatisticsInfoRspVo = FindDashboardStatisticsInfoRspVo
                .builder()
                .articleTotalCount(articleTotalCount)
                .categoryTotalCount(categoryTotalCount)
                .pvTotalCount(pvTotalCount)
                .tagTotalCount(tagTotalCount)
                .build();

        return Response.success(findDashboardStatisticsInfoRspVo);
    }

    @Override
    public Response findDashboardPublishArticleStatistics() {
        // 当前日期
        LocalDate nowDate = LocalDate.now();
        LocalDateTime nowDateTime = LocalDateTime.now();
        // 当前日期倒退一年日期
        LocalDate oneYearAgoDate = nowDate.minusYears(1);
        LocalDateTime startDateTime = nowDateTime.minusYears(1);
        // 查询数据
        List<ArticlePublishCountDo> articlePublishCountDos = articleMapper.selectDateArticlePublishCount(startDateTime, nowDateTime);

        // 转map
        Map<LocalDate, Long> map = null;

        if(!CollectionUtils.isEmpty(articlePublishCountDos)) {
            //do 转 map
            Map<LocalDate, Long> dateLongMap = articlePublishCountDos.stream()
                    .collect(Collectors.toMap(ArticlePublishCountDo::getDate, ArticlePublishCountDo::getCount));
            // 转换为treemap，升序排列
            map = Maps.newTreeMap();
            for (LocalDate currDate = oneYearAgoDate; currDate.isBefore(nowDate) || currDate.isEqual(nowDate); currDate = currDate.plusDays(1)) {
                Long count = dateLongMap.get(currDate);
                // 设置到新的map
                map.put(currDate, Objects.isNull(count) ? 0 : count);
            }
        }

        return Response.success(map);
    }

    @Override
    public Response findDashboardPvForLastestWeekStatistics() {
        // 获取数据
        List<StatisticsArticlePvDo> statisticsArticlePvDos = statisticsArticlePvMapper.selectLatestWeekRecords();
        Map<LocalDate, Long> map = Maps.newHashMap();
        if (!CollectionUtils.isEmpty(statisticsArticlePvDos)) {
            // 转map
            map = statisticsArticlePvDos.stream().collect(Collectors.toMap(StatisticsArticlePvDo::getPvDate, StatisticsArticlePvDo::getPvCount));
        }
        // 日期
        List<String> pvDates = Lists.newArrayList();
        // pv count
        List<Long> pvCounts = Lists.newArrayList();

        // 当前日期
        LocalDate currDate = LocalDate.now();
        // 一周前日期
        LocalDate temDate = currDate.minusWeeks(1);
        for(; temDate.isBefore(currDate) || temDate.isEqual(currDate); temDate = temDate.plusDays(1)) {
            // 将map中数据转移到list中
            pvDates.add(temDate.format(Constants.MONTH_DAY_FORMATTER));
            pvCounts.add(map.getOrDefault(temDate, 0L));
        }
        FindDashboardPvStatisticsInfoRspVo findDashboardPvStatisticsInfoRspVo = FindDashboardPvStatisticsInfoRspVo
                .builder()
                .pvCounts(pvCounts)
                .pvDates(pvDates)
                .build();

        return Response.success(findDashboardPvStatisticsInfoRspVo);
     }
}
